<template>
  <!--不写template页面会有警告-->
  <span></span>
</template>
<script type="text/javascript">
import { pick, get, isEmpty, throttle } from 'lodash'
import bus from '@/store/eventBus'
export const ACCEPT = 'accept'
export const REFUSE = 'refuse'
const CANCEL = 'cancel'
const NO_BTN_LIMIT = 2
const NEW_TRANSFER = 'lastRedirectTime'

export default {
  name: "webChatTransferNotice",
  data() {
    return {
      notificationQueue: [],
      listMsg: {},
      infoMap: new Map([
        [ACCEPT, () => this.$t("public.accept")],
        [REFUSE, () => this.$t("public.refuse")],
      ]),
    };
  },
  computed: {
    transferBackInfo() {
      const backRes = this.message.redirectResponse;
      if (!backRes) {
        return "";
      }
      return this.infoMap.get(backRes)();
    },
    channelId() {
      return (
        get(this.message, "redirectData._id") ||
        this.message._id ||
        this.message.chatSessionId
      );
    },
    message() {
      const notice = get(this, "$store.state.transferNotice");
      if (!isEmpty(notice)) {
        return notice;
      }
      const confirmNotice = get(this, "$store.state.transferNoConfirmNotice");
      return !isEmpty(confirmNotice) ? confirmNotice : this.listMsg;
    },
    autoCloseQueue() {
      return this.notificationQueue.filter(
        (i) => !get(i, "channel.redirectData.redirectWebchatSessionConfirmFlag")
      );
    },
    inLimit() {
      if (isEmpty(this.autoCloseQueue)) {
        return true;
      }
      return this.autoCloseQueue.length < NO_BTN_LIMIT;
    },
  },
  watch: {
    message: {
      async handler(newVal) {
        if (!isEmpty(newVal)) {
          const isCancel = newVal.redirectRequest === CANCEL;
          const isNewTransfer = newVal[NEW_TRANSFER]
          if (isNewTransfer) {
            const { 
              redirectWebchatSessionConfirmFlag,
              redirectWebchatSessionCommentFlag
            } = await this.getTransferConfig()
            if (redirectWebchatSessionConfirmFlag) {
              return
            }
            if (
              !redirectWebchatSessionConfirmFlag && 
              !redirectWebchatSessionCommentFlag
            ) {
              return
            }
          }
          if (isCancel) {
            return this.closeSingleNotification(newVal);
          }
          this.closeNotificationQueue();
          this.openMessageTips(newVal);
          this.$store.dispatch('refreshWebchatMenuNum')
        }
      },
      immediate: true,
      deep: true,
    },
  },
  mounted() {
    this.getRemainList();
  },
  methods: {
    async getTransferConfig() {
      const res = await this.$store.dispatch('getDicByType', { type: 'redirectWebchatSessionCofing' })
      return res.row || {}
    },
    getChannelId(channel) {
      return (
        get(channel, "redirectData._id") || channel._id || channel.chatSessionId
      );
    },
    sleep(time) {
      return new Promise((resolve) => setTimeout(resolve, time));
    },
    async getRemainList() {
      const res = await this.$store.dispatch("getRedirectRemind");
      // console.log(res)
      const list = res.list;
      if (isEmpty(list)) {
        return;
      }
      for (const val of list) {
        const newVal = this.transRemainToMsg(val);
        this.listMsg = newVal;
        await this.sleep(500);
      }
    },
    transRemainToMsg(data) {
      return data
    },
    async makeAction(action, channel) {
      const param = {
        ...pick(channel, ["redirectData", "redirectSession"]),
        redirectResponse: action,
      };
      await this.$store.dispatch("redirectSessionCallback", param);
      this.closeSingleNotification(channel);
    },
    async onReject(channel) {
      await this.makeAction(REFUSE, channel);
      this.updateChannel(channel);
    },
    async onAccept(channel) {
      await this.makeAction(ACCEPT, channel);
      this.$store.commit("BLANK", "webchat_todo");
      this.$router.replace({ path: "/index/webchat/webchat_todo" });
      this.updateChannel(channel);
    },
    updateNotificationQueue({ channel, notify }) {
      if (this.notificationQueue.some((i) => i.id === this.channelId)) {
        return;
      }
      this.notificationQueue.push({
        id: this.channelId,
        channel,
        notify,
      });
    },
    getNotifyDom(channel) {
      const ctxDom = [...document.querySelectorAll('.el-notification')]
      if (isEmpty(ctxDom)) {
        return ctxDom
      }
      const channelId = this.getChannelId(channel)
      return ctxDom.filter(i => 
        i.querySelector('.notify-ctx') ? 
        i.querySelector('.notify-ctx').getAttribute('transfer-id') === channelId :
        false
      )
    },
    destroyDom(doms) {
      if (isEmpty(doms)) {
        return
      }
      doms.forEach(i => {
        const closeBtn = i.querySelector('.el-notification__closeBtn')
        closeBtn.click()
        setTimeout(() => i.parentNode.removeChild(i))
      })
    },
    closeSingleNotification(channel) {
      const id = this.getChannelId(channel);
      const { notify } = this.notificationQueue.find((i) => get(i, 'id') === id) || {};
      const notifyDoms = this.getNotifyDom(channel)
      this.destroyDom(notifyDoms) // hack 提示销毁不了的容错处理
      if (!notify) {
        return;
      }
      notify.close();
      setTimeout(() =>
        this.$set(
          this,
          "notificationQueue",
          this.notificationQueue.filter((i) => get(i, 'id') !== id)
        )
      );
    },
    closeNotificationQueue() {
      // 自动关闭的notice只能同时存在两个
      // console.log('***inLimit***', this.inLimit)
      if (this.inLimit) {
        return;
      }
      const oldList = this.autoCloseQueue.filter(
        (_, m) => m + 1 < NO_BTN_LIMIT
      );
      // console.log('***oldList***', this.autoCloseQueue, oldList)
      oldList.forEach((i) => {
        get(i, "notify.close")();
      });
      this.$set(
        this,
        "notificationQueue",
        this.notificationQueue.filter((i) =>
          oldList.every((m) => m.id !== i.id)
        )
      );
    },
    updateChannel(channel) {
      this.$store.commit("webchat/UPDATE_WEBCHAT_TODO", {
        channelId: this.getChannelId(channel),
        key: "redirectToUser",
        val: null,
      });
    },
    openMessageTips: throttle(
      function (message) {
        if (message.hasInstance) {
          return;
        }
        return new Promise((resolve) => {
          const _this = this;
          const h = this.$createElement;
          // console.log('***message***', message)
          const remark =
            get(message, "redirectData.redirectWebchatSessionComment") ||
            message.remark ||
            message.redirectWebchatSessionComment;
          const displayName =
            get(message, "redirectSession.user.displayName") ||
            message.displayName ||
            message.fromUserName;
          const showBtn = get(
            message,
            "redirectData.redirectWebchatSessionConfirmFlag"
          );
          if (this.transferBackInfo) {
            const name = get(message, "redirectData.toUserName", "");
            setTimeout(() => {
              this.$notify({
                title: this.$t("public.tip"),
                message: `${name}${this.$t("webchat.hasDoneTransfer", {
                  action: this.transferBackInfo,
                })}`,
                customClass: "transfer-notification",
                duration: 5000,
              });
              bus.$emit("initTransferRequest");
              if (message.redirectResponse === ACCEPT) {
                this.$store.commit("BLANK", "webchat_todo");
                this.$router.replace({ path: "/index/webchat/webchat_todo" });
                this.updateChannel(message);
                this.$store.dispatch('redirectWebchatSession', {
                  onlyUpdate: true,
                  _id: this.getChannelId(message)
                })
              } else {
                this.updateChannel(message);
              }
              resolve();
            }, 500);
            return;
          }
          if (!displayName) {
            return;
          }
          this.$nextTick(() => {
            const notify = this.$notify({
              title: this.$t("public.tip"),
              dangerouslyUseHTMLString: true,
              customClass: "transfer-notification",
              message: h("div", {
                attrs: {
                  class: 'notify-ctx',
                  'transfer-id': this.getChannelId(message)
                }
              }, [
                h(
                  "div",
                  {
                    style: {
                      display: "flex",
                    },
                  },
                  [
                    h("i", {
                      class: "el-icon-warning",
                      style: {
                        color: "#f9ae0f",
                        marginRight: "10px",
                        fontSize: "20px",
                      },
                    }),
                    h("div", null, [
                      h(
                        "p",
                        {
                          style: {
                            fontSize: "14px",
                            fontWeight: 500,
                            color: "#000",
                          },
                        },
                        showBtn
                          ? this.$t("webchat.transferRequestConfirm", {
                              displayName,
                            })
                          : this.$t("webchat.transferRequest", { displayName })
                      ),
                      remark
                        ? h(
                            "span",
                            {
                              style: {
                                fontSize: "12px",
                                color: "#aaa",
                                display: "inline-block",
                                width: "230px",
                                wordBreak: "break-all",
                              },
                            },
                            `${this.$t("public.note")}：${remark}`
                          )
                        : null,
                    ]),
                  ]
                ),
                showBtn
                  ? h(
                      "div",
                      {
                        style: {
                          marginTop: "20px",
                          position: "relative",
                          right: "-20px",
                          textAlign: "right",
                        },
                      },
                      [
                        h(
                          "el-button",
                          {
                            props: {
                              size: "small",
                            },
                            on: {
                              click: _this.onReject.bind(_this, message),
                            },
                          },
                          this.$t("public.refuse")
                        ),
                        h(
                          "el-button",
                          {
                            props: {
                              type: "primary",
                              size: "small",
                            },
                            on: {
                              click: _this.onAccept.bind(_this, message),
                            },
                          },
                          this.$t("public.accept")
                        ),
                      ]
                    )
                  : null,
              ]),
              duration: showBtn ? 0 : 5000,
            });
            Object.assign(message, { hasInstance: true });
            this.updateNotificationQueue({ channel: message, notify });
            resolve();
          });
        });
      },
      500,
      { trailing: false }
    ),
  },
};
</script>
<style lang="stylus">
  .transfer-notification
    z-index 99999999998 !important
</style>
<style lang="stylus" scoped>
.dialog-footer
  text-align right
.ml10
  margin-left 10px
</style>
